package com.corechina.apex_osswords.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.corechina.apex_osswords.common.*;
import com.corechina.apex_osswords.common.config.WeiXinConfig;
import com.corechina.apex_osswords.domain.dao.*;
import com.corechina.apex_osswords.domain.dto.CoreWeiXinUserBindAppletsDto;
import com.corechina.apex_osswords.domain.dto.TokenNeedFieldDto;
import com.corechina.apex_osswords.domain.entity.CoreMaintenanceEngineer;
import com.corechina.apex_osswords.domain.entity.CoreUserBinding;
import com.corechina.apex_osswords.domain.entity.SysLogs;
import com.corechina.apex_osswords.domain.entity.SysUserToken;
import com.corechina.apex_osswords.service.ICoreWeiXinUser;
import com.corechina.apex_osswords.service.IRedisService;
import com.corechina.apex_osswords.service.ISysLogsService;
import com.corechina.apex_osswords.service.ISysUserTokenService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: apex_osswords
 * @description: 微信用户实现逻辑类
 * @author: cc
 * @create: 2022-03-29 10:47
 **/

@Service
public class CoreWeiXinUserImpl implements ICoreWeiXinUser {

    @Autowired
    private CoreMaintenanceEngineerMapper coreMaintenanceEngineerMapper;

    @Autowired
    private IRedisService iRedisService;

    @Autowired
    private ISysLogsService iSysLogsService;

    @Autowired
    private CoreUserBindingMapper coreUserBindingMapper;

    @Autowired
    private SysUserTokenMapper sysUserTokenMapper;

    @Autowired
    private CoreWeiXinMapper coreWeiXinMapper;

    @Autowired
    private ISysUserTokenService iSysUserTokenService;

    @Autowired
    private CoreEnterpriseEngineerMapper coreEnterpriseEngineerMapper;

    @Override
    public Response getOpenId(String code) {
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("appid", WeiXinConfig.APP_ID);
            param.put("secret", WeiXinConfig.APP_SECRET);
            param.put("js_code", code);
            param.put("grant_type", WeiXinConfig.GRANT_TYPE);

            String wxResult = HttpUtil.get(WeiXinConfig.WX_LOGIN_URL, param, null);
            JSONObject jsonObject = JSONObject.parseObject(wxResult);
            String sessionKey = jsonObject.get("session_key").toString();
            String openId = jsonObject.get("openid").toString();
            return Response.ok(openId);
        } catch (Exception e) {
            return Response.error("获取openId失败");
        }
    }

    public Response bindApplets(CoreWeiXinUserBindAppletsDto coreWeiXinUserBindAppletsDto) {
        Date nowTime = new Date();
        SysLogs sysLogs = new SysLogs();
        sysLogs.setCreateTime(nowTime);
        sysLogs.setIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
        sysLogs.setOperation("微信绑定小程序");
        if (coreWeiXinUserBindAppletsDto.getCode() == null || coreWeiXinUserBindAppletsDto.getOpenId() == null || "".equals(coreWeiXinUserBindAppletsDto.getOpenId().trim()) || coreWeiXinUserBindAppletsDto.getTel() == null) {
            sysLogs.setAfterData("绑定失败，信息不完整");
            iSysLogsService.add(sysLogs);
            return Response.error("信息不完整，无法绑定");
        }

        Integer userId;
        String userName;
        CoreMaintenanceEngineer coreMaintenanceEngineer = coreMaintenanceEngineerMapper.selectOne(new QueryWrapper<CoreMaintenanceEngineer>().eq("tel", coreWeiXinUserBindAppletsDto.getTel()));
        if (coreMaintenanceEngineer == null) {
            return Response.error("绑定失败，该手机号未预留在系统中");
        }
        userId = coreMaintenanceEngineer.getId();
        userName = coreMaintenanceEngineer.getName();

        CoreUserBinding coreUserBinding = coreUserBindingMapper.selectOne(new QueryWrapper<CoreUserBinding>().eq("user_id", userId));
        if (coreUserBinding != null) {
            sysLogs.setAfterData("绑定失败，该手机号已绑定" + coreWeiXinUserBindAppletsDto.getTel());
            iSysLogsService.add(sysLogs);
            return Response.error("绑定失败，该手机号已绑定");
        }

        CoreUserBinding coreUserBinding1 = coreUserBindingMapper.selectOne(new QueryWrapper<CoreUserBinding>().eq("open_id", coreWeiXinUserBindAppletsDto.getOpenId()));
        if (coreUserBinding1 != null) {
            sysLogs.setAfterData("绑定失败,该微信已绑定" + coreWeiXinUserBindAppletsDto.getTel());
            iSysLogsService.add(sysLogs);
            return Response.error("该微信已绑定");
        }

        String code = iRedisService.get(coreWeiXinUserBindAppletsDto.getTel());
        if (code == null || code.trim().equals("")) {
            sysLogs.setAfterData("绑定失败,验证码过期" + coreWeiXinUserBindAppletsDto.getTel());
            iSysLogsService.add(sysLogs);
            return Response.error("验证码已过期,请重新发送");
        }
        if (!code.equals(coreWeiXinUserBindAppletsDto.getCode())) {
            sysLogs.setAfterData("绑定失败，验证码错误");
            iSysLogsService.add(sysLogs);
            return Response.error("验证码错误");
        }

        CoreUserBinding coreUserBinding2 = new CoreUserBinding();
        coreUserBinding2.setOpenId(coreWeiXinUserBindAppletsDto.getOpenId());
        coreUserBinding2.setUserId(userId);
        if (coreUserBindingMapper.insert(coreUserBinding2) > 0) {
            sysLogs.setOperator(userId);
            sysLogs.setAfterData(coreWeiXinUserBindAppletsDto.toString());
            iSysLogsService.add(sysLogs);
            return this.getToken(userId, 1, userName);
        }
        sysLogs.setAfterData("绑定失败");
        iSysLogsService.add(sysLogs);
        return Response.error("绑定失败");
    }

    @Override
    public Response sendCode(String tel, Integer userType, HttpSession httpSession) {
        try {

            CoreMaintenanceEngineer coreMaintenanceEngineer = coreMaintenanceEngineerMapper.selectOne(new QueryWrapper<CoreMaintenanceEngineer>().eq("tel", tel));
            if (coreMaintenanceEngineer == null) {
                return Response.error("发送失败，该手机号未预留在系统中");
            } else if (coreMaintenanceEngineer.getForbidden().equals(1)) {
                return Response.error("非系统人员或账号已禁用，请联系管理员");
            }

            return this.sendVerificationCode(tel, httpSession);
        } catch (Exception e) {
            return Response.error("验证码发送失败");
        }
    }

    private Response sendVerificationCode(String tel, HttpSession httpSession) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //获取session中的时间，判断时间差是否一分钟
            Object sessionTime = httpSession.getAttribute("time");
            String nowTime = sdf.format(new Date());
            long min = 0;
            if (sessionTime != null) {
                String sessionTimeFormat = sdf.format(sessionTime);
                long diff = sdf.parse(nowTime).getTime() - sdf.parse(sessionTimeFormat).getTime();
                long day = diff / (24 * 60 * 60 * 1000);
                long hour = (diff / (60 * 60 * 1000) - day * 24);
                min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
            }
            if (sessionTime == null || min >= 1) {
                Credential cred = new Credential("AKIDQgyue8ZM5Xk4nq5OozvfIp67tPjntmY3", "NWQ5VerqZ1DAtMczC9pGSN2r9G7h1Aj9");
                HttpProfile httpProfile = new HttpProfile();
                httpProfile.setReqMethod("POST");
                httpProfile.setConnTimeout(60);
                httpProfile.setEndpoint("sms.tencentcloudapi.com");

                ClientProfile clientProfile = new ClientProfile();
                clientProfile.setSignMethod("HmacSHA256");
                clientProfile.setHttpProfile(httpProfile);

                SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
                SendSmsRequest req = new SendSmsRequest();
                req.setSmsSdkAppId(TencentSmsConstant.APP_ID);
                req.setSignName("灵睿运维通");
                req.setTemplateId(TencentSmsConstant.TEMPLATE_ID);

                //生成随机验证码
                String randomCode = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
                String[] templateParamSet = {randomCode, "5"};
                req.setTemplateParamSet(templateParamSet);

                // 需要发送短信的手机号码
                String[] phoneNumbers = {"86" + tel};
                req.setPhoneNumberSet(phoneNumbers);

                String sessionContext = "";
                req.setSessionContext(sessionContext);

                String extendCode = "";
                req.setExtendCode(extendCode);

                String senderid = "";
                req.setSenderId(senderid);

                SendSmsResponse res = client.SendSms(req);
                iRedisService.remove(tel);
                iRedisService.set(tel, randomCode);
                iRedisService.expire(tel, 300);
                return Response.ok("发送成功");
            } else {
                return Response.ok("一分钟之内不允许重复发送");
            }

        } catch (Exception e) {
            return Response.error("发送失败");
        }
    }

    public Response loginByWeiXin(String openId) {
        SysLogs sysLogs = new SysLogs();
        sysLogs.setCreateTime(new Date());
        sysLogs.setIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
        sysLogs.setOperation("微信账户登录");

        CoreUserBinding coreUserBinding = coreUserBindingMapper.selectOne(new QueryWrapper<CoreUserBinding>().eq("open_id", openId));
        if (coreUserBinding == null) {
            sysLogs.setAfterData("登录失败，账户未绑定");
            iSysLogsService.add(sysLogs);
            return Response.error(5001, "登录失败，账户未绑定");
        }

        CoreMaintenanceEngineer coreMaintenanceEngineer = coreMaintenanceEngineerMapper.selectById(coreUserBinding.getUserId());
        if (coreMaintenanceEngineer == null || coreMaintenanceEngineer.getForbidden().equals(1)) {
            sysLogs.setAfterData("登录失败，账号不存在或已被禁用");
            iSysLogsService.add(sysLogs);
            return Response.error(5002, "登录失败，账号不存在或已被禁用");
        }
        return this.getToken(coreUserBinding.getUserId(), 1, coreMaintenanceEngineer.getName());

    }

    private Response getToken(Integer userId, Integer loginType, String userName) {
        SysLogs sysLogs = new SysLogs();
        sysLogs.setCreateTime(new Date());
        sysLogs.setIp(IPUtils.getIpAddr(HttpContextUtils.getHttpServletRequest()));
        sysLogs.setOperation("微信账户登录");
        SysUserToken sysUserToken = sysUserTokenMapper.getByUserId(userId, loginType);
        if (sysUserToken != null) {
            //判断token是否过期
            if (sysUserToken.getExpireTime().getTime() > System.currentTimeMillis()) {
                sysUserToken.setUpdateTime(new Date());
                if (sysUserTokenMapper.updateUserTokenInfo(sysUserToken) > 0) {
                    sysLogs.setOperator(userId);
                    sysLogs.setAfterData("登录成功");
                    iSysLogsService.add(sysLogs);
                    return Response.ok(coreWeiXinMapper.getWeiXinUserInfo(userId, loginType));
                } else {
                    sysLogs.setAfterData(userId + "登录失败");
                    iSysLogsService.add(sysLogs);
                    return Response.error("登录失败");
                }
            }
        }
        TokenNeedFieldDto tokenNeedFieldDto = new TokenNeedFieldDto();
        tokenNeedFieldDto.setId(userId);
        tokenNeedFieldDto.setName(userName);
        tokenNeedFieldDto.setSecret(new Md5Hash("Apex", userId.toString()).toString());
        //生成token，并保存到数据库
        sysUserToken = iSysUserTokenService.saveToken(tokenNeedFieldDto, loginType);
        if (sysUserToken != null) {
            return Response.ok(coreWeiXinMapper.getWeiXinUserInfo(userId, loginType));
        }

        return Response.error("登录失败");
    }

    @Override
    public Response updateLoginEnterprise(Integer enterpriseId) {
        if (coreEnterpriseEngineerMapper.checkEngineer(enterpriseId, WeiXinUserUtils.getUserId()) == 0) {
            return Response.error("非该企业相关人员");
        }
        sysUserTokenMapper.updateEnterpriseId(enterpriseId, WeiXinUserUtils.getUserId());
        return Response.ok();
    }

    @Override
    public Response getEnterpriseList() {
        return Response.ok(coreEnterpriseEngineerMapper.getEnterpriseList(WeiXinUserUtils.getUserId()));
    }
}
